import React, { useState, useRef } from 'react';
import { Upload, Button, Progress, message, Modal, List, Typography, Space, Tag } from 'antd';
import { UploadOutlined, InboxOutlined, DeleteOutlined, FileOutlined } from '@ant-design/icons';
import type { UploadProps, UploadFile } from 'antd';
import { fileService, FileUploadProgress } from '@/services/fileService';

const { Dragger } = Upload;
const { Text } = Typography;

interface FileUploadProps {
  folderId?: string;
  multiple?: boolean;
  accept?: string;
  maxSize?: number; // MB
  maxCount?: number;
  onUploadSuccess?: (files: any[]) => void;
  onUploadError?: (error: string) => void;
  className?: string;
  style?: React.CSSProperties;
}

interface UploadingFile {
  id: string;
  name: string;
  size: number;
  progress: number;
  status: 'uploading' | 'completed' | 'failed';
  error?: string;
}

export default function FileUpload({
  folderId,
  multiple = true,
  accept,
  maxSize = 100, // 默认100MB
  maxCount = 10,
  onUploadSuccess,
  onUploadError,
  className,
  style
}: FileUploadProps) {
  const [uploadingFiles, setUploadingFiles] = useState<UploadingFile[]>([]);
  const [isModalVisible, setIsModalVisible] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);

  // 格式化文件大小
  const formatFileSize = (bytes: number): string => {
    if (bytes === 0) return '0 B';
    const k = 1024;
    const sizes = ['B', 'KB', 'MB', 'GB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
  };

  // 验证文件
  const validateFile = (file: File): string | null => {
    // 检查文件大小
    if (file.size > maxSize * 1024 * 1024) {
      return `文件大小不能超过 ${maxSize}MB`;
    }

    // 检查文件类型
    if (accept) {
      const acceptedTypes = accept.split(',').map(type => type.trim());
      const fileExtension = '.' + file.name.split('.').pop()?.toLowerCase();
      const mimeType = file.type;
      
      const isAccepted = acceptedTypes.some(type => {
        if (type.startsWith('.')) {
          return fileExtension === type.toLowerCase();
        }
        return mimeType.match(type.replace('*', '.*'));
      });

      if (!isAccepted) {
        return `不支持的文件类型，仅支持: ${accept}`;
      }
    }

    return null;
  };

  // 处理文件选择
  const handleFileSelect = async (files: FileList | File[]) => {
    const fileArray = Array.from(files);
    
    // 检查文件数量
    if (uploadingFiles.length + fileArray.length > maxCount) {
      message.error(`最多只能上传 ${maxCount} 个文件`);
      return;
    }

    const validFiles: File[] = [];
    const errors: string[] = [];

    // 验证每个文件
    fileArray.forEach(file => {
      const error = validateFile(file);
      if (error) {
        errors.push(`${file.name}: ${error}`);
      } else {
        validFiles.push(file);
      }
    });

    // 显示验证错误
    if (errors.length > 0) {
      Modal.error({
        title: '文件验证失败',
        content: (
          <div>
            <p>以下文件验证失败：</p>
            <ul>
              {errors.map((error, index) => (
                <li key={index}>{error}</li>
              ))}
            </ul>
          </div>
        )
      });
    }

    // 上传有效文件
    if (validFiles.length > 0) {
      await uploadFiles(validFiles);
    }
  };

  // 上传文件
  const uploadFiles = async (files: File[]) => {
    const newUploadingFiles: UploadingFile[] = files.map(file => ({
      id: Math.random().toString(36).substr(2, 9),
      name: file.name,
      size: file.size,
      progress: 0,
      status: 'uploading'
    }));

    setUploadingFiles(prev => [...prev, ...newUploadingFiles]);
    setIsModalVisible(true);

    const uploadPromises = files.map(async (file, index) => {
      const uploadingFile = newUploadingFiles[index];
      
      try {
        const result = await fileService.uploadFile(
          file,
          folderId,
          (progress: FileUploadProgress) => {
            setUploadingFiles(prev => 
              prev.map(f => 
                f.id === uploadingFile.id 
                  ? { ...f, progress: progress.progress, status: progress.status }
                  : f
              )
            );
          }
        );

        // 上传成功
        setUploadingFiles(prev => 
          prev.map(f => 
            f.id === uploadingFile.id 
              ? { ...f, progress: 100, status: 'completed' }
              : f
          )
        );

        return result;
      } catch (error: any) {
        // 上传失败
        const errorMessage = error.message || '上传失败';
        setUploadingFiles(prev => 
          prev.map(f => 
            f.id === uploadingFile.id 
              ? { ...f, status: 'failed', error: errorMessage }
              : f
          )
        );
        
        if (onUploadError) {
          onUploadError(errorMessage);
        }
        
        throw error;
      }
    });

    try {
      const results = await Promise.allSettled(uploadPromises);
      const successResults = results
        .filter(result => result.status === 'fulfilled')
        .map(result => (result as PromiseFulfilledResult<any>).value);
      
      if (successResults.length > 0 && onUploadSuccess) {
        onUploadSuccess(successResults);
      }

      // 显示结果消息
      const successCount = successResults.length;
      const failCount = results.length - successCount;
      
      if (successCount > 0) {
        message.success(`成功上传 ${successCount} 个文件`);
      }
      
      if (failCount > 0) {
        message.error(`${failCount} 个文件上传失败`);
      }
    } catch (error) {
      console.error('批量上传失败:', error);
    }
  };

  // 处理拖拽上传
  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault();
    const files = e.dataTransfer.files;
    if (files.length > 0) {
      handleFileSelect(files);
    }
  };

  // 处理文件输入
  const handleFileInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const files = e.target.files;
    if (files && files.length > 0) {
      handleFileSelect(files);
    }
    // 清空input值，允许重复选择同一文件
    e.target.value = '';
  };

  // 移除上传中的文件
  const removeUploadingFile = (id: string) => {
    setUploadingFiles(prev => prev.filter(f => f.id !== id));
  };

  // 重试上传
  const retryUpload = async (uploadingFile: UploadingFile) => {
    // 这里需要重新获取原始文件，实际项目中可能需要不同的实现
    message.info('重试功能需要重新选择文件');
  };

  // 获取状态颜色
  const getStatusColor = (status: string) => {
    switch (status) {
      case 'uploading': return 'processing';
      case 'completed': return 'success';
      case 'failed': return 'error';
      default: return 'default';
    }
  };

  const uploadProps: UploadProps = {
    name: 'file',
    multiple,
    accept,
    showUploadList: false,
    beforeUpload: () => false, // 阻止自动上传
    onChange: (info) => {
      if (info.fileList.length > 0) {
        const files = info.fileList.map(file => file.originFileObj!).filter(Boolean);
        handleFileSelect(files);
      }
    }
  };

  return (
    <div className={className} style={style}>
      {/* 拖拽上传区域 */}
      <Dragger
        {...uploadProps}
        onDrop={handleDrop}
        style={{ marginBottom: 16 }}
      >
        <p className="ant-upload-drag-icon">
          <InboxOutlined />
        </p>
        <p className="ant-upload-text">点击或拖拽文件到此区域上传</p>
        <p className="ant-upload-hint">
          支持单个或批量上传。{accept && `支持格式: ${accept}`}
          {maxSize && ` 最大文件大小: ${maxSize}MB`}
        </p>
      </Dragger>

      {/* 按钮上传 */}
      <Space>
        <Button 
          icon={<UploadOutlined />} 
          onClick={() => fileInputRef.current?.click()}
        >
          选择文件
        </Button>
        <input
          ref={fileInputRef}
          type="file"
          multiple={multiple}
          accept={accept}
          style={{ display: 'none' }}
          onChange={handleFileInputChange}
        />
        {uploadingFiles.length > 0 && (
          <Button onClick={() => setIsModalVisible(true)}>
            查看上传进度 ({uploadingFiles.length})
          </Button>
        )}
      </Space>

      {/* 上传进度模态框 */}
      <Modal
        title="文件上传进度"
        open={isModalVisible}
        onCancel={() => setIsModalVisible(false)}
        footer={[
          <Button key="close" onClick={() => setIsModalVisible(false)}>
            关闭
          </Button>
        ]}
        width={600}
      >
        <List
          dataSource={uploadingFiles}
          renderItem={(file) => (
            <List.Item
              actions={[
                file.status === 'failed' && (
                  <Button 
                    type="link" 
                    size="small" 
                    onClick={() => retryUpload(file)}
                  >
                    重试
                  </Button>
                ),
                <Button 
                  type="link" 
                  size="small" 
                  icon={<DeleteOutlined />}
                  onClick={() => removeUploadingFile(file.id)}
                  danger
                >
                  移除
                </Button>
              ].filter(Boolean)}
            >
              <List.Item.Meta
                avatar={<FileOutlined />}
                title={
                  <Space>
                    <span>{file.name}</span>
                    <Tag color={getStatusColor(file.status)}>
                      {file.status === 'uploading' ? '上传中' :
                       file.status === 'completed' ? '已完成' : '失败'}
                    </Tag>
                  </Space>
                }
                description={
                  <div>
                    <Text type="secondary">{formatFileSize(file.size)}</Text>
                    {file.error && (
                      <div>
                        <Text type="danger">{file.error}</Text>
                      </div>
                    )}
                    <Progress 
                      percent={file.progress} 
                      size="small" 
                      status={file.status === 'failed' ? 'exception' : undefined}
                      style={{ marginTop: 4 }}
                    />
                  </div>
                }
              />
            </List.Item>
          )}
        />
      </Modal>
    </div>
  );
}

// 导出类型
export type { FileUploadProps };